#include "common/linkage.h"
#include "i386/kernel/segment.h"
#include "linux/irq_vector.h"

	.extern idt_table
	.extern start_kernel
	.global cpu_gdt_table
	
	.code32
	.section "init.text32", "ax"
ENTRY(startup_32)
	/*
	* 初始化新的 gdt和idt
	*/	
	lgdt	cpu_gdt_descr
	lidt	idt_descr
	
	/*
	* 为何数据区域要使用用户数据呢？
	*/
	movl	$(__USER_DS), %eax
	movl	%eax, %es
	movl	%eax, %ds

	/*
	* Init Pagging Dir
	*/
	movl	$pg0, %edi
	movl	$swapper_pg_dir, %edx
	movl	$0x007, %eax /* PRESENT + RW + USER */
10:
	leal	0x007(%edi), %ecx
	movl	%ecx, (%edx)
	movl	%ecx, page_pgd_offset(%edx)
	addl	$4, %edx
	movl	$1024, %ecx
11:
	stosl
	addl	$0x1000, %eax
	loop	11b

	/*
	* enable pagging
	*/
	movl	$swapper_pg_dir, %eax
	movl	%eax, %cr3
	movl	%cr0, %eax
	orl	$0x80000000, %eax
	movl	%eax, %cr0

	ljmp	$(__KERNEL_CS),$1f
1:	movl	$(__KERNEL_DS), %eax
	mov	%eax, %ss
	
	jmp	start_kernel

idt_descr:
	.word	NR_VECTORS * 8 - 1
	.long   idt_table

cpu_gdt_descr:
	.word  GDT_ENTRIES * 8 - 1
	.long  cpu_gdt_table
	/* .fill  NR_CPUS - 1, 8, 0 */
	
	.align	4
ENTRY(cpu_gdt_table)
	.quad 0x0000000000000000        /* NULL descriptor */
        .quad 0x0000000000000000        /* 0x0b reserved */
        .quad 0x0000000000000000        /* 0x13 reserved */
        .quad 0x0000000000000000        /* 0x1b reserved */
        .quad 0x0000000000000000        /* 0x20 unused */
        .quad 0x0000000000000000        /* 0x28 unused */
        .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
        .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
        .quad 0x0000000000000000        /* 0x43 TLS entry 3 */
        .quad 0x0000000000000000        /* 0x4b reserved */
        .quad 0x0000000000000000        /* 0x53 reserved */
        .quad 0x0000000000000000        /* 0x5b reserved */
        .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
	.quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */

        .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
        .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */

	.quad 0x0000000000000000        /* 0x80 TSS descriptor */
        .quad 0x0000000000000000        /* 0x88 LDT descriptor */

	/* Segments used for calling PnP BIOS */
        .quad 0x00c09a0000000000        /* 0x90 32-bit code */
        .quad 0x00809a0000000000        /* 0x98 16-bit code */
        .quad 0x0080920000000000        /* 0xa0 16-bit data */
        .quad 0x0080920000000000        /* 0xa8 16-bit data */
        .quad 0x0080920000000000        /* 0xb0 16-bit data */
        /*
         * The APM segments have byte granularity and their bases
         * and limits are set at run time.
         */
        .quad 0x00409a0000000000        /* 0xb8 APM CS    code */
        .quad 0x00009a0000000000        /* 0xc0 APM CS 16 code (16 bit) */
        .quad 0x0040920000000000        /* 0xc8 APM DS    data */
        .quad 0x0000000000000000        /* 0xd0 - unused */
        .quad 0x0000000000000000        /* 0xd8 - unused */
        .quad 0x0000000000000000        /* 0xe0 - unused */
        .quad 0x0000000000000000        /* 0xe8 - unused */
        .quad 0x0000000000000000        /* 0xf0 - unused */
        .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
